﻿
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.lock
Imports osi.root.utils
Imports counter = osi.root.utils.counter

Public Class device_pool
    Implements idevice_pool
    Protected ReadOnly mc As UInt32
    Protected ReadOnly id As String
    Private ReadOnly count As atomic_int32
    Private ReadOnly TOTAL_COUNT_COUNTER As Int64
    Private ReadOnly FREE_COUNT_COUNTER As Int64
    Private exp As singleentry

    Public Sub New(ByVal max_count As UInt32, ByVal identity As String)
        assert(Not String.IsNullOrEmpty(identity))
        Me.mc = max_count
        Me.count = New atomic_int32()
        Me.id = identity
        strtoupper(identity)
        Me.TOTAL_COUNT_COUNTER = counter.register_average_and_last_average(strcat(identity, "_DEVICE_TOTAL_COUNT"),
                                                                           last_average_length:=256,
                                                                           sample_rate:=1)
        Me.FREE_COUNT_COUNTER = counter.register_average_and_last_average(strcat(identity, "_DEVICE_FREE_COUNT"),
                                                                          last_average_length:=256,
                                                                          sample_rate:=1)
        assert(exp.not_in_use())
    End Sub

    Private Function assert_decrease_total_count() As UInt32
        Dim r As Int32 = 0
        r = count.decrement()
        assert(r >= 0)
        Return r
    End Function

    Protected Function increase_total_count() As Boolean
        If limited_max_count() Then
            Dim r As Int32 = 0
            r = count.increment()
            If r > mc Then
                assert_decrease_total_count()
                Return False
            Else
                counter.increase(TOTAL_COUNT_COUNTER, r)
                Return True
            End If
        Else
            counter.increase(TOTAL_COUNT_COUNTER, count.increment())
            Return True
        End If
    End Function

    Protected Sub zero_total_count()
        count.set(0)
    End Sub

    Protected Sub decrease_total_count()
        Dim r As Int32 = 0
        r = assert_decrease_total_count()
        counter.increase(TOTAL_COUNT_COUNTER, r)
    End Sub

    Protected Sub decrease_total_count(ByVal i As UInt32)
        If i > 0 Then
            Dim r As Int32 = 0
            r = count.add(-CInt(i))
            assert(r >= 0)
            counter.increase(TOTAL_COUNT_COUNTER, r)
        End If
    End Sub

    Protected Overrides Sub Finalize()
        close()
        MyBase.Finalize()
        GC.KeepAlive(exp)
    End Sub
End Class
